﻿using SGLisp;
using System.Collections.Generic;
using System;

namespace SGLib.AITree
{
    public enum AINodeType
    {
        Func,
        Seq,
        Select,
        Sync
    }

    public class AITree
    {
        AINode mRootNode;
        AITreeContext mTreeContext;
        Context mContext;
        public Context Context { get { return mContext; } }

        public void Init(AITreeContext treeContext, Context context)
        {
            mContext = context;
            mTreeContext = treeContext;
        }
        
        public void Load(string scriptPath)
        {
            ASTTree astTree = RT.LoadASTTree(scriptPath);
          
            this.mRootNode = this.ParseNode(astTree.Roots[0]);
        }

        public AINode ParseNode(ASTNode node)
        { 
            if (node.NodeType != ASTNode.ASTNodeType.ListNode)
            {
                throw new Exception("AITree的顶层节点必须是ListNode");
            }
            string firstSymName = ((SymbolNode)((ListNode)node).nodes.First.Value).Val;
            switch (firstSymName)
            {
                case "seq-node":
                    AISeqNode seqNode = new AISeqNode(this);
                    seqNode.Load((ListNode)node);
                    return seqNode;
                case "sync-node":
                    AISyncNode syncNode = new AISyncNode(this);
                    syncNode.Load((ListNode)node);
                    return syncNode;
                case "case-node":
                    AICaseNode caseNode = new AICaseNode(this);
                    caseNode.Load((ListNode)node);
                    return caseNode;
                default:
                    AINode RegNode =  this.mTreeContext.GetRegisterNode(firstSymName);
                    if (RegNode != null)
                    {
                        RegNode.Init(this, null);
                        RegNode.Load((ListNode)node);
                        return RegNode;
                    }
                    else
                    {
                        AIFuncNode funcNode = new AIFuncNode();
                        funcNode.Init(this,null);
                        funcNode.Load((ListNode)node);
                        return funcNode;
                    }
            }
        }

        public void Run()
        {
            this.mRootNode.OnEnter(mContext);
        }

        public void Update(float dt)
        {
            this.mRootNode.Update(mContext,dt);
        }
    }
}
